using MicroMsg.Common.Algorithm;
using MicroMsgBackground.Common.Utils;
using MicroMsgBackground.Network;
using System;
namespace MicroMsgBackground.Protocol
{
	public class MMPack
	{
		private const string TAG = "MMPack";
		public static bool EncodePack(SessionPack sessionPack)
		{
			bool result;
			try
			{
				byte[] array = sessionPack.requestToByteArray();
				byte[] sessionKey = sessionPack.getSessionKey(true);
				MMTLVHeader mMTLVHeader = new MMTLVHeader();
				mMTLVHeader.Ret = (int)ConstantsProtocol.CLIENT_VERSION;
				mMTLVHeader.Uin = (uint)SessionPackMgr.getAccount().getUin();
				mMTLVHeader.CmdId = (ushort)sessionPack.getMMFuncID();
				mMTLVHeader.ServerId = SessionPackMgr.getSeverID();
				mMTLVHeader.DeviceId = Util.StringToByteArray(Util.getDeviceUniqueId());
				mMTLVHeader.CompressLen = (uint)array.Length;
				mMTLVHeader.CompressVersion = 1001;
				byte[] array2 = null;
				if (sessionPack.mNeedCompress)
				{
					mMTLVHeader.CompressAlogrithm = 1;
					if (!Zlib.Compress(array, ref array2))
					{
						Log.smethod_1("MMPack", " Zlib Compress failed");
						result = false;
						return result;
					}
				}
				else
				{
					Log.smethod_6("MMPack", " no Compress ..");
					mMTLVHeader.CompressAlogrithm = 2;
					array2 = array;
				}
				mMTLVHeader.CompressedLen = (uint)array2.Length;
				short mEncrypt = sessionPack.mEncrypt;
				byte[] array3 = null;
				if (sessionKey != null && sessionKey.Length > 0)
				{
					if (mEncrypt == 5)
					{
						Log.smethod_6("MMPack", "aes encrypt start,data length = " + array2.Length);
						mMTLVHeader.CryptAlgorithm = 5;
						array3 = AES.Encrypt(array2, sessionKey);
						if (array3 == null)
						{
							Log.smethod_1("MMPack", "AES: AESEncrypt failed");
							result = false;
						}
						else
						{
							Log.smethod_6("MMPack", "aes encrypt end");
							result = MMPack.Pack(ref sessionPack.mCacheBodyBuffer, mMTLVHeader, array3);
						}
					}
					else
					{
						Log.smethod_6("MMPack", "des encrypt start,data length = " + array2.Length);
						mMTLVHeader.CryptAlgorithm = 4;
						array3 = DES.EncryptBytes(array2, sessionKey, 1);
						if (array3 == null)
						{
							Log.smethod_1("MMPack", "DES: DESEncrypt failed");
							result = false;
						}
						else
						{
							Log.smethod_6("MMPack", "des encrypt end");
							result = MMPack.Pack(ref sessionPack.mCacheBodyBuffer, mMTLVHeader, array3);
						}
					}
				}
				else
				{
					if (RSA.RSAEncrypt(out array3, array2) != 0)
					{
						Log.smethod_1("MMPack", " RSAEncrypt failed");
						result = false;
					}
					else
					{
						result = MMPack.Pack(ref sessionPack.mCacheBodyBuffer, mMTLVHeader, array3);
					}
				}
			}
			catch (Exception ex)
			{
				Log.smethod_1("MMPack", ex.get_Message());
				result = false;
			}
			return result;
		}
		public static bool DecodePack(ref byte[] decryptedData, byte[] packBuf, byte[] byte_0, ref byte[] serverId, ref int int_0)
		{
			bool result;
			try
			{
				if (packBuf != null && packBuf.Length >= 2)
				{
					MMTLVHeader mMTLVHeader = new MMTLVHeader();
					byte[] array = null;
					if (!MMPack.UnPack(packBuf, ref mMTLVHeader, ref array))
					{
						Log.smethod_1("MMPack", " UnPack failed");
						result = false;
					}
					else
					{
						int_0 = mMTLVHeader.Ret;
						if (mMTLVHeader.Ret == -13)
						{
							Log.smethod_1("MMPack", "DecodPack failed : session timeout");
							result = false;
						}
						else
						{
							if (mMTLVHeader.Ret != 0)
							{
								Log.smethod_1("MMPack", "DecodPack failed : retCode = " + mMTLVHeader.Ret);
								result = false;
							}
							else
							{
								serverId = mMTLVHeader.ServerId;
								Log.smethod_6("MMPack", "tlvHeader.cryptalgorithm = " + mMTLVHeader.CryptAlgorithm);
								byte[] array2;
								if (mMTLVHeader.CryptAlgorithm == 5)
								{
									Log.smethod_6("MMPack", "aes decrypt start,data length = " + array.Length);
									decryptedData = AES.Decrypt(array, byte_0);
									if (decryptedData == null)
									{
										Log.smethod_1("MMPack", "AES: AESDecrypt failed");
										result = false;
										return result;
									}
									array2 = decryptedData;
									Log.smethod_6("MMPack", "aes decrypt end");
								}
								else
								{
									if (mMTLVHeader.CryptAlgorithm == 0)
									{
										array2 = array;
										Log.smethod_5("MMPack", "not encrypt");
									}
									else
									{
										int num = array.Length + 32;
										decryptedData = new byte[num];
										Log.smethod_6("MMPack", "des decrypt start,data length = " + array.Length);
										if (DES.Using_DES(decryptedData, ref num, array, array.Length, byte_0, byte_0.Length, 2) == 0)
										{
											Log.smethod_1("MMPack", "DES: DESDecrypt failed");
											result = false;
											return result;
										}
										Log.smethod_6("MMPack", "des decrypt end");
										array2 = new byte[num];
										Array.Copy(decryptedData, array2, array2.Length);
									}
								}
								if (mMTLVHeader.CompressAlogrithm == 1)
								{
									if (!Zlib.Decompress(array2, (int)mMTLVHeader.CompressLen, ref decryptedData))
									{
										Log.smethod_1("MMPack", " Zlib Compress failed");
										result = false;
									}
									else
									{
										result = true;
									}
								}
								else
								{
									if (mMTLVHeader.CompressAlogrithm == 2)
									{
										decryptedData = array2;
										result = true;
									}
									else
									{
										result = false;
									}
								}
							}
						}
					}
				}
				else
				{
					result = false;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}
		private static bool Pack(ref byte[] packBuf, MMTLVHeader tlvHeader, byte[] data)
		{
			TLVPack tLVPack = new TLVPack(0, 1);
			tLVPack.addByte(1, 190);
			tLVPack.AddInt(2, (int)tlvHeader.Uin);
			tLVPack.AddWord(3, (int)tlvHeader.CmdId);
			tLVPack.AddInt(4, tlvHeader.ServerId.Length);
			tLVPack.addByteArray(5, tlvHeader.ServerId, tlvHeader.ServerId.Length);
			tLVPack.addByteArray(6, tlvHeader.DeviceId, 16);
			tLVPack.AddWord(7, (int)tlvHeader.CompressVersion);
			tLVPack.AddWord(8, (int)tlvHeader.CompressAlogrithm);
			tLVPack.AddWord(9, (int)tlvHeader.CryptAlgorithm);
			tLVPack.AddInt(10, (int)tlvHeader.CompressLen);
			tLVPack.AddInt(11, (int)tlvHeader.CompressedLen);
			tLVPack.addByteArray(12, data, data.Length);
			tLVPack.AddInt(13, tlvHeader.Ret);
			tLVPack.addByte(14, 237);
			packBuf = new byte[tLVPack.getUsedSize() + 2];
			packBuf[0] = 190;
			packBuf[packBuf.Length - 1] = 237;
			int num = 0;
			num = tLVPack.getUsedSize();
			if (tLVPack.CopyTo(packBuf, 1, ref num) != 0)
			{
				Log.smethod_1("MMPack", "tlvPack.CopyTo failed");
				return false;
			}
			return true;
		}
		public static bool UnPack(byte[] packBuf, ref MMTLVHeader tlvHeader, ref byte[] cipherText)
		{
			if (packBuf != null && packBuf.Length >= 2)
			{
				if (190 == packBuf[0])
				{
					if (237 == packBuf[packBuf.Length - 1])
					{
						TLVPack tLVPack = new TLVPack(0, 1);
						if (tLVPack.CopyFrom(packBuf, packBuf.Length - 2, 1) != 0)
						{
							return false;
						}
						int uin = 0;
						if (tLVPack.GetInt(2, ref uin) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : uin");
							return false;
						}
						tlvHeader.Uin = (uint)uin;
						short num = 0;
						if (tLVPack.GetShort(3, ref num) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : cmdId");
							return false;
						}
						tlvHeader.CmdId = (ushort)num;
						byte[] serverId = null;
						if (tLVPack.getByteArray(5, ref serverId) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : serverId");
							return false;
						}
						tlvHeader.ServerId = serverId;
						byte[] deviceId = null;
						if (tLVPack.getByteArray(6, ref deviceId) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : deviceId");
							return false;
						}
						tlvHeader.DeviceId = deviceId;
						short compressVersion = 0;
						if (tLVPack.GetShort(7, ref compressVersion) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : compressVersion");
							return false;
						}
						tlvHeader.CompressVersion = compressVersion;
						short compressAlogrithm = 0;
						if (tLVPack.GetShort(8, ref compressAlogrithm) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : compressAlgorithm");
							return false;
						}
						tlvHeader.CompressAlogrithm = compressAlogrithm;
						short cryptAlgorithm = 0;
						if (tLVPack.GetShort(9, ref cryptAlgorithm) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : cryptAlgorithm");
							return false;
						}
						tlvHeader.CryptAlgorithm = cryptAlgorithm;
						uint compressLen = 0u;
						if (tLVPack.GetUInt(10, ref compressLen) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : compressLen");
							return false;
						}
						tlvHeader.CompressLen = compressLen;
						uint compressedLen = 0u;
						if (tLVPack.GetUInt(11, ref compressedLen) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : compressedLen");
							return false;
						}
						tlvHeader.CompressedLen = compressedLen;
						if (tLVPack.getByteArray(12, ref cipherText) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : cipherText");
							return false;
						}
						int ret = 0;
						if (tLVPack.GetInt(13, ref ret) != 0)
						{
							Log.smethod_1("MMPack", " UnPack failed : ret");
							return false;
						}
						tlvHeader.Ret = ret;
						return true;
					}
				}
				Log.smethod_1("MMPack", " UnPack failed: invalid args packBuf");
				return false;
			}
			Log.smethod_1("MMPack", " UnPack failed: invlaide args");
			return false;
		}
	}
}
